<?php
/**
 * +--------------------------------------------------------------
 * | eLuoPHP
 * +--------------------------------------------------------------
 * | Copyright (c) 2016-2018 http://qxwoo.cn All rights reserved.
 * +--------------------------------------------------------------
 * | y139w [y139w@163.com]
 * +--------------------------------------------------------------
 * | 请求处理类文件
 * +--------------------------------------------------------------
 */

namespace luo;


class Request
{

    private static $_instance = null;

    /**
     * 请求的原始数据
     * @var bool|string
     */
    private $input;

    /**
     * PATH_INFO
     * @var string
     */
    private $pathinfo;

    /**
     * 模块
     * @var string
     */
    private $module = '';

    /**
     * 控制器
     * @var string
     */
    private $controller = '';

    /**
     * 方法
     * @var string
     */
    private $action = '';

    /**
     * $_SERVER
     * @var array
     */
    private $server = [];

    /**
     * Request constructor.
     */
    public function __construct()
    {
        $this->input = file_get_contents('php://input');
        $this->server = $_SERVER;
        self::$_instance = $this;
    }

    /**
     * 静态方法实例化Request类
     * @return Request
     */
    public static function instance(){

        if( !(self::$_instance instanceof self) ){
            self::$_instance = new static();
        }
        return self::$_instance;

    }


    /**
     * 获取GET请求的参数
     * @param string $name
     * @param bool $default
     * @param array $options
     * @return array|mixed|null
     */
    public function get($name = '', $default = false, array $options = []){

        $get = $_GET;
        return $this->input($get, $name, $default, $options);

    }

    /**
     * 获取POST请求的参数
     * @param string $name
     * @param bool $default
     * @param array $options
     * @return mixed|null
     */
    public function post($name = '', $default = false, array $options = []){

        $post = $_POST;

        return $this->input($post, $name, $default, $options);

    }

    /**
     * 获取PUT请求的参数
     * @param string $name
     * @param bool $default
     * @param array $options
     * @return array|mixed|null
     */
    public function put($name = '', $default = false, array $options = []){
        parse_str($this->input, $put);
        return $this->input($put, $name, $default, $options);
    }

    /**
     * 获取DELETE请求的参数
     * @param string $name
     * @param bool $default
     * @param array $options
     * @return array|mixed|null
     */
    public function delete($name = '', $default = false, array $options = []){

        $input = $this->put($name, $options);
        return $this->input($input, $name, $default, $options);

    }

    /**
     * 获取上传文件信息
     * @return bool
     */
    public function files(){

        return empty($_FILES) ? false : $_FILES;

    }

    /**
     * 判断是否为GET请求
     * @return bool
     */
    public function isGet(){

        if($this->server('REQUEST_METHOD') == 'GET'){
            return true;
        }
        return false;

    }

    /**
     * 判断是否为POST请求
     * @return bool
     */
    public function isPost(){

        if($this->server('REQUEST_METHOD') == 'POST'){
            return true;
        }
        return false;

    }

    /**
     * 判断是否为PUT请求
     * @return bool
     */
    public function isPut(){

        if($this->server('REQUEST_METHOD') == 'PUT'){
            return true;
        }
        return false;

    }

    /**
     * 判断是否为DELETE请求
     * @return bool
     */
    public function isDelete(){

        if($this->server('REQUEST_METHOD') == 'DELETE'){
            return true;
        }
        return false;

    }

    /**
     * 判断是否为AJAX请求
     * @return bool
     */
    public function isAjax(){

        if(
            $this->server("HTTP_X_REQUESTED_WITH") &&
            strtolower($this->server("HTTP_X_REQUESTED_WITH"))=="xmlhttprequest"
        ){
            return true;
        }
        return false;

    }

    /**
     * 获取请求的参数
     * @param string $name
     * @param bool $default
     * @param array $options
     * @return array|mixed|null
     */
    public function request($name = '', $default = false, array $options = []){

        $request = $_REQUEST;
        return $this->input($request, $name, $default, $options);

    }

    /**
     * 获取$_SERVER信息
     * @param string $name
     * @param bool $default
     * @param array $options
     * @return array|mixed|null
     */
    public function server($name = '', $default = false, array $options = []){
        $server = $this->server;
        return $this->input($server, $name, $default, $options);

    }

    /**
     * 获取或设置模块
     * @param string $module
     * @return $this|string
     */
    public function module($module = ''){

        if(!empty($module)){
            $this->module = $module;
            return $this;
        }
        return $this->module;

    }

    /**
     * 获取或设置控制器
     * @param string $controller
     * @return $this|string
     */
    public function controller($controller = ''){

        if(!empty($controller)){
            $this->controller = $controller;
            return $this;
        }
        return $this->controller;

    }

    /**
     * 获取或设置方法
     * @param string $action
     * @return $this|string
     */
    public function action($action = ''){

        if(!empty($action)){
            $this->action = $action;
            return $this;
        }
        return $this->action;

    }

    /**
     * 输入值处理，过滤非法字符
     * @param $data
     * @param $name
     * @param $default
     * @param array $options
     * @return array|mixed|null
     */
    public function input($data, $name, $default, array $options = []){

        if(empty($data)){
            if(is_string($name) && $default){
                return $default;
            }else{
                return null;
            }
        }else{
            if(is_string($data)){
                return $this->filter($data, $options);
            }
            if(is_array($data)){
                if(!empty($name) && isset($data[$name])){
                    if(empty($data[$name]) && $default){
                        $data[$name] = $default;
                    }
                    return $this->filter($data[$name], $options);
                }
                if(!empty($name) && is_string($name) && !isset($data[$name])){
                    if($default){
                        return $default;
                    }else{
                        return null;
                    }
                }
            }

            if(empty($data) && is_string($name)){
                if($default){
                    echo 3;
                    return $default;
                }else{
                    return null;
                }
            }

        }
        return $this->filter($data, $options);

    }


    /**
     * 获取PATH_INFO
     * @return string
     */
    public function pathinfo(){

        if(isset($_GET[Config::get('var_pathinfo')])){
            $_SERVER['PATH_INFO'] = $_GET[Config::get('var_pathinfo')];
            unset($_GET[Config::get('var_pathinfo')]);
        }
        if(isset($_SERVER['PATH_INFO'])){
            $this->pathinfo = $_SERVER['PATH_INFO'];
        }
        return $this->pathinfo;

    }

    /**
     * 请求数据过滤
     * @param $data
     * @param array $options
     * @return mixed
     */
    private function filter($data, array $options = []){

        if(is_string($data)){
            $data = htmlspecialchars(addslashes(trim($data)));
        }
        if(is_array($data)){
            foreach($data as $key=>$val){
                $data[$key] = $this->filter($val);
            }
        }

        return $data;

    }

    /**
     * 获取相对根路径
     * @return mixed|string
     */
    public function root(){

        $script_filename = $_SERVER['SCRIPT_FILENAME'];
        $document_root = !empty($_SERVER['DOCUMENT_ROOT'])
            ? $_SERVER['DOCUMENT_ROOT']
            : (empty($_SERVER['CONTEXT_DOCUMENT_ROOT']) ? '' : $_SERVER['CONTEXT_DOCUMENT_ROOT']);

        $dirs = dirname($script_filename);
        $root = str_replace($document_root, '', $dirs);

        $root = ($root == '/') ? '/' : $root . '/';

        return $root;

    }

    /**
     * 获取IP地址
     * @return array|false|mixed|string|null
     */
    public function ip(){

        static $realIp = null;

        if(!is_null($realIp)){
            return $realIp;
        }

        //判断服务器是否允许$_SERVER
        if($this->server()){
            $realIp = $this->server('HTTP_X_FORWARDED_FOR');
            if(!$realIp){
                $realIp = $this->server('HTTP_CLIENT_IP');
            }
            if(!$realIp){
                $realIp = $this->server('REMOTE_ADDR');
            }
        }else{
            //不允许就使用getenv获取
            if(getenv("HTTP_X_FORWARDED_FOR")){
                $realIp = getenv( "HTTP_X_FORWARDED_FOR");
            }elseif(getenv("HTTP_CLIENT_IP")) {
                $realIp = getenv("HTTP_CLIENT_IP");
            }else{
                $realIp = getenv("REMOTE_ADDR");
            }
        }

        return $realIp;

    }

}
